#version 120

uniform sampler2D backfacetexture;
uniform sampler3D volumetexture;

uniform sampler1D tranf;

uniform float stepsize;
uniform float begin;

varying vec4 vposition;
varying vec3 eposition;
uniform vec4 lightposition;


const float shininess = 5;
const float diffuse = 0.0;
const float specular = 1.0;


float rand(vec2 co)
{        
	return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453) / 200;        
} 

float offset(vec2 xy)
{
	return fract((xy.x)*1.298/10+(xy.y)/10)/800;
}

void main()
{
	vec2 texposition = ((vposition.xy/vposition.w) + 1.0)/2.0;

	vec2 interleavePosf = vec2(texposition.x*1600, texposition.y*1200);
	ivec2 interleavePos;
	interleavePos.x = int(floor(interleavePosf.x + 0.5));
	interleavePos.y = int(floor(interleavePosf.y + 0.5));

	interleavePos.x = int(mod(interleavePos.x,8));
	interleavePos.y = int(mod(interleavePos.y,8));

	float offset = offset(interleavePos);

	vec4 start = gl_TexCoord[0];
	vec3 dir;
	vec4 backposition1 = texture2D(backfacetexture, texposition);
	dir.x = backposition1.x - start.x;
	dir.y = backposition1.y - start.y;
	dir.z = backposition1.z - start.z;
	float len = length(dir);
	vec3 norm_dir = normalize(dir);
	float iso_value = 0.3;

   float delta = stepsize;
   vec3 delta_dir = norm_dir * delta;
   float delta_dir_len = length(delta_dir);
   vec3 vec = start.xyz;
   vec4 col_acc = vec4(0,0,0,0);
   float alpha_acc = 0;
   float length_acc = 0;
   vec4 color_sample=vec4(0,0,0,0);
   float alpha_sample=0;
  
  vec4 colorvalue; 
  for(int i = 0; i < 400; i++)
    {
      color_sample = texture3D(volumetexture,vec);
	  if(color_sample.x > iso_value)
	  {
		  //gl_FragColor = vec4(0.0,1,0,1);
		  break;
	  }
	  vec += delta_dir;
      length_acc += delta_dir_len;
	  if(length_acc >= len)
		  discard;
  }

  vec3 delta_e = delta_dir/2;
  vec -= delta_e;
  length_acc -= length(delta_e);
  		  
  for(int j=0; j<6; j++)
  {
      color_sample = texture3D(volumetexture,vec);
	  if(color_sample.x < iso_value)
	  {
		  vec += delta_e;
		  length_acc += length(delta_e);
	  }
	  else
	  {
		  vec -= delta_e;
		  length_acc -= length(delta_e);
	  }
	  delta_e = delta_e/2;
  }

  //calculate Normal
  vec3 Normal;
  Normal.x = (texture3D(volumetexture,vec+vec3(2.0/256.0,0,0))-texture3D(volumetexture,vec+vec3(-2.0/256.0,0,0))).x;
  Normal.y = (texture3D(volumetexture,vec+vec3(0,2.0/256.0,0))-texture3D(volumetexture,vec+vec3(0,-2.0/256.0,0))).x;
  Normal.z = (texture3D(volumetexture,vec+vec3(0,0,2.0/256.0))-texture3D(volumetexture,vec+vec3(0,0,-2.0/256.0))).x;
  
  Normal = normalize(Normal);
  vec3 LightVec = normalize(lightposition.xyz/lightposition.w - eposition);
  vec3 eye = -normalize(eposition.xyz);
  float NormalColor = max(0,dot(Normal,LightVec));
  vec3 HalfVec = normalize(LightVec + eye);
  float SpecularColor = max(0,pow(dot(Normal, HalfVec),shininess));
  

  //vec4 fangcolor = vec4(NormalColor,NormalColor,NormalColor,diffuse) + vec4(SpecularColor,SpecularColor,SpecularColor,specular);


  //float elipse = rand(vec2(length_acc,alpha_acc));
  vec += vec3(0, 0, offset);
  
  alpha_acc = 0;

  int i = 0;
  for(i = 0; i < 300; i++)
    {
      color_sample = texture3D(volumetexture,vec);
      colorvalue = texture1D(tranf, color_sample.x);
      alpha_sample = texture1D(tranf, color_sample.x).x;
	  alpha_sample/=5;

      col_acc   += (1.0 - alpha_acc) * colorvalue.xxxx*alpha_sample;
      alpha_acc += alpha_sample;
      vec += delta_dir;
      length_acc += delta_dir_len;
      if(length_acc >= len || alpha_acc > 1.0 || col_acc.x > 1.0) break; // terminate if opacity > 1 or the ray is outside the volume
    }
  float tempc = float(i)/100;

 	  if (col_acc.x<1.0&&col_acc.x>0.001) 
	  {
		  //gl_FragColor = (alpha_acc)*col_acc + (1-alpha_acc)*vec4(0,0,0.4,1);
		  gl_FragColor = vec4(vec3(tempc,0,0),alpha_acc)+vec4(0.4,0.4,0.4,1-alpha_acc);
		 
	  }
	  else if (col_acc.x<0.001) 
	  {
		  gl_FragColor = vec4(0,0,1,1);
		 
	  }

	  else if (abs(col_acc.x - col_acc.y)>0.00001)
	  {
		  gl_FragColor = vec4(0,1,0,1);
	  }
	  else
	  {
		//gl_FragColor = (alpha_acc-begin)*col_acc + begin*fangcolor + (1-alpha_acc)*vec4(0,0,0.4,1);
		//gl_FragColor = (alpha_acc)*col_acc + (1-alpha_acc)*vec4(0,0,0.4,1);
		  gl_FragColor = vec4(1,0,0,1);
	  }
	  
}
